﻿/*
 * Created by SharpDevelop.
 * User: Masy Freddy
 * Date: 12/10/2011
 * Time: 5:33
 */
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

using MetaVideoEditorEvolved.AddIn.AddInViews;
using MetaVideoEditorEvolved.AddIn.Entity;
using MetaVideoEditorEvolved.Helper;

namespace SaverXBMC
{
	[System.AddIn.AddIn("XBMC Saver", Version = "1.0.0.0", Description = "XBMC Saver", Publisher = "Masy Freddy")]
	public class XBMC : SaverView
	{
		private const string MovieFileName = "movie.nfo",
		MoviePosterFileName = "movie.tbn",
		FanArtFileName = "fanart.jpg",
		ExtraFanArtDirectory = "extrafanart",
		SeriePoster = "folder.jpg",
		SerieFileName = "tvshow.nfo",
		EpisodePoster = "episode.tbn",
		EpisodeFileName = "episode.nfo",
		SeasonPoster = "season$$.tbn",
		ActorFileName = "folder.jpg",
		BannerFileName = "banner.jpg";
		
		private ConfigurationAddIn configurationAddIn;
		
		public XBMC()
		{
			configurationAddIn = ConfigurationManager.Deserialize();
			
			if(configurationAddIn == null)
			{
				configurationAddIn = new ConfigurationAddIn();
				configurationAddIn.UseExtraFanArt = true;
				configurationAddIn.TraceLevel = "Error";
				ConfigurationManager.Serialize(configurationAddIn);
			}

			Tracer.TracerInstance.Level= string.IsNullOrEmpty(configurationAddIn.TraceLevel) ? TracerLevel.Error : (TracerLevel)Enum.Parse(typeof(TracerLevel), configurationAddIn.TraceLevel);
			Tracer.TracerInstance.FileName = "XbmcSaver";
		}
		
		public override void SaveMovie(string mediaLocation, MetaVideoEditorEvolved.AddIn.Entity.Movie movieMVEE)
		{
			try
			{
				movie movieXBMC = new movie();

				movieXBMC.title = movieMVEE.Title;
				movieXBMC.originaltitle = movieMVEE.OriginalTitle;
				movieXBMC.sorttitle = movieMVEE.SortTitle;
				movieXBMC.country = movieMVEE.Countries.ToArray();
				movieXBMC.studio = movieMVEE.Studios.ToArray();
				movieXBMC.mpaa = movieMVEE.MPAARating;
				movieXBMC.rating = movieMVEE.Rating.ToString();
				movieXBMC.runtime = movieMVEE.Duration.ToString();
				movieXBMC.year = movieMVEE.Year.ToString();
				movieXBMC.plot = movieXBMC.outline = movieMVEE.Overview;
				movieXBMC.actor = (from actor in movieMVEE.CastMembers
				                   where actor.Activity.ToLower().Contains("act")
				                   select new movieActor
				                   {
				                   	name = actor.FullName,
				                   	role = actor.Role,
				                   	thumb = SaveActor(mediaLocation, actor.Picture, actor.FullName)
				                   }).ToArray();
				
				movieXBMC.director= (from director in movieMVEE.CastMembers
				                     where director.Activity.ToLower() == "director" || 
				                     director.Activity.ToLower() == "réalisateur"
				                     select director.FullName).ToArray();
				
				if(configurationAddIn.DeleteImage)
				{
					foreach (var element in Directory.GetFiles(mediaLocation, "*.tbn")) {
						File.Delete(element);
					}
				}
				
				if(configurationAddIn.UseMovieNameNfo)
				{
					var fi = new FileInfo(movieMVEE.FullPath);
					SavePoster(movieMVEE.Posters, mediaLocation, fi.Name.Replace(fi.Extension, ".tbn"));
				}
				else
				{
					SavePoster(movieMVEE.Posters, mediaLocation, MoviePosterFileName);
				}
				
				SaveBackdrops(movieMVEE.Backdrops, mediaLocation, movieMVEE.FullPath);
				SaveTrailer(movieMVEE.Trailers, mediaLocation);

				//TODO:Not Yet implemented
				// movieXBMC.fileinfo;
				// movieXBMC.filenameandpath;
				// movieXBMC.id;
				// movieXBMC.playcount;
				// movieXBMC.set;
				// movieXBMC.tagline;
				// movieXBMC.top250;
				// movieXBMC.votes;
				// movieXBMC.watched;
				// movieXBMC.thumb;
				
				if(configurationAddIn.DeleteImage)
				{
					foreach (var element in Directory.GetFiles(mediaLocation, "*.nfo")) {
						File.Delete(element);
					}
				}
				
				if(configurationAddIn.UseMovieNameNfo)
				{
					var fi = new FileInfo(movieMVEE.FullPath);
					using (StreamWriter sw = new StreamWriter(Path.Combine(mediaLocation, fi.Name.Replace(fi.Extension, ".nfo")), false))
					{
						new XmlSerializer(typeof(movie)).Serialize(sw, movieXBMC);
					}
				}
				else
				{
					using (StreamWriter sw = new StreamWriter(Path.Combine(mediaLocation, MovieFileName), false))
					{
						new XmlSerializer(typeof(movie)).Serialize(sw, movieXBMC);
					}
				}
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(string.Format("Exception XBMC SaveMovie mediaLocation={0}", mediaLocation),ex);
				throw;
			}
		}
		
		public override void SaveSerie(string mediaLocation, MetaVideoEditorEvolved.AddIn.Entity.Serie serieMVEE)
		{
			try
			{
				tvshow serieXBMC = new tvshow();
				
				serieXBMC.actor = (from actor in serieMVEE.CastMembers
				                   where actor.Activity.ToLower().Contains("act")
				                   select new tvshowActor
				                   {
				                   	name = actor.FullName,
				                   	role = actor.Role,
				                   	thumb = SaveActor(mediaLocation, actor.Picture, actor.FullName)
				                   }).ToArray();
				
				serieXBMC.director= (from director in serieMVEE.CastMembers
				                     where director.Activity.ToLower().Contains("direct")
				                     select director.FullName).ToArray();
				serieXBMC.genre = serieMVEE.Genres.ToArray();
				serieXBMC.id = serieMVEE.Id;
				serieXBMC.plot = serieXBMC.outline = serieMVEE.Overview;
				serieXBMC.rating = serieMVEE.Rating.ToString();
				serieXBMC.runtime = serieMVEE.Duration.ToString();
				
				serieXBMC.studio = serieMVEE.Studios.ToArray();
				serieXBMC.title = serieMVEE.Name;
				serieXBMC.year = serieMVEE.Year.ToString();
				
				SavePoster(serieMVEE.Posters, mediaLocation, SeriePoster);
				SaveBackdrops(serieMVEE.Backdrops, mediaLocation, string.Empty);
				SavePoster(serieMVEE.Graphicals, mediaLocation, BannerFileName);
				
				//TODO:Not yet implemented
				//serieXBMC.aired;
				//serieXBMC.artist;
				//serieXBMC.code;
				//serieXBMC.credits;
				//serieXBMC.displayepisode;
				//serieXBMC.displayseason;
				//serieXBMC.episode;
				//serieXBMC.episodeguide;
				//serieXBMC.fanart;
				//serieXBMC.lastplayed;
				//serieXBMC.mpaa;
				//serieXBMC.playcount;
				//serieXBMC.premiered;
				//serieXBMC.season;
				//serieXBMC.set;
				//serieXBMC.status;
				//serieXBMC.tagline;
				//serieXBMC.thumb;
				//serieXBMC.top250;
				//serieXBMC.trailer;
				//serieXBMC.votes;
				
				using (StreamWriter sw = new StreamWriter(Path.Combine(mediaLocation, SerieFileName), false))
				{
					new XmlSerializer(typeof(tvshow)).Serialize(sw, serieXBMC);
				}
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(string.Format("Exception XBMC SaveSerie mediaLocation={0}", mediaLocation), ex);
				throw;
			}
		}
		
		public override void SaveSeason(string mediaLocation, MetaVideoEditorEvolved.AddIn.Entity.Season seasonMVEE)
		{
			try
			{
				if(seasonMVEE.Images.Any())
				{
					DirectoryInfo di = new DirectoryInfo(mediaLocation);

					var primarySeasonPoster = seasonMVEE.Images.First();
					
					if(!primarySeasonPoster.AbsoluteUri.Contains("http"))
					{
						File.Copy(primarySeasonPoster.LocalPath, Path.Combine(di.Parent.FullName, SeasonPoster.Replace("$$", seasonMVEE.Number.ToString().PadLeft(2,'0'))), true);
					}
				}
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(string.Format("Exception XBMC SaveSeason mediaLocation={0}", mediaLocation) , ex);
				throw;
			}
		}
		
		public override void SaveEpisode(string mediaLocation, MetaVideoEditorEvolved.AddIn.Entity.Episode episodeMVEE)
		{
			try
			{
				FileInfo fi = new FileInfo(mediaLocation);
				
				episodedetails episodeXBMC = new episodedetails();
				
				episodeXBMC.actor = (from gs in episodeMVEE.GuestStars
				                     select new episodedetailsActor
				                     {
				                     	name = gs
				                     }).ToArray();
				episodeXBMC.director = episodeMVEE.Directors.ToArray();
				episodeXBMC.episode = episodeMVEE.Number.ToString();
				episodeXBMC.plot = episodeMVEE.Overview;
				episodeXBMC.rating = episodeMVEE.Rating.ToString();
				episodeXBMC.season = episodeMVEE.SeasonNumber.ToString();
				episodeXBMC.title = episodeMVEE.Name;
				episodeXBMC.aired = episodeMVEE.FirstAired;
				
				SavePoster(episodeMVEE.Images, mediaLocation, fi.Name.Replace(fi.Extension, string.Empty) + ".tbn");
				
				//TODO:Not yet implemented
				//episodeXBMC.aired;
				//episodeXBMC.credits;
				//episodeXBMC.displayepisode;
				//episodeXBMC.displayseason;
				//episodeXBMC.epbookmark;
				//episodeXBMC.fileinfo;
				//episodeXBMC.lastplayed;
				//episodeXBMC.mpaa;
				//episodeXBMC.playcount;
				//episodeXBMC.premiered;
				//episodeXBMC.thumb;
				//episodeXBMC.studio;
				
				DirectoryInfo di= new DirectoryInfo(mediaLocation);
				
				if(File.Exists(mediaLocation))
				{
					di = di.Parent;
				}
				
				using (StreamWriter sw = new StreamWriter(Path.Combine(di.FullName, fi.Name.Replace(fi.Extension, string.Empty) + ".nfo"), false))
				{
					new XmlSerializer(typeof(episodedetails)).Serialize(sw, episodeXBMC);
				}
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(string.Format("Exception XBMC SaveEpisode mediaLocation={0}", mediaLocation), ex);
				throw;
			}
		}
		
		public override void ShowOption()
		{
			new Option(configurationAddIn).ShowDialog();
		}
		
		public override bool HasOption()
		{
			return true;
		}
		
		private void SavePoster(List<Uri> posters, string mediaLocation, string posterFileName)
		{
			if(posters.Any())
			{
				DirectoryInfo di= new DirectoryInfo(mediaLocation);
				
				if(File.Exists(mediaLocation))
				{
					di = di.Parent;
				}

				var primaryPoster = posters.First();
				
				if(!primaryPoster.AbsoluteUri.Contains("http"))
				{
					File.Copy(primaryPoster.LocalPath, Path.Combine(di.FullName, posterFileName), true);
				}
			}
		}
		
		private void SaveBackdrops(List<Uri> backdrops, string mediaLocation, string fullPath)
		{
			if(backdrops.Any())
			{
				DirectoryInfo di = new DirectoryInfo(mediaLocation);
				
				if(File.Exists(mediaLocation))
				{
					di = di.Parent;
				}
				
				var primaryBackdrop = backdrops.First();
				
				if(configurationAddIn.DeleteImage)
				{
				foreach (var element in Directory.GetFiles(mediaLocation, "*fanart*.*")) {
						File.Delete(element);
					}
				}
				
				if(configurationAddIn.UseMovieNameNfo &&
				   !string.IsNullOrEmpty(fullPath))
				{
					if(!primaryBackdrop.AbsoluteUri.Contains("http"))
					{
						var fi = new FileInfo(fullPath);
						File.Copy(primaryBackdrop.LocalPath, Path.Combine(di.FullName, fi.Name.Replace(fi.Extension, string.Empty) + "-fanart.jpg"),true);
					}
				}
				else
				{
					if(!primaryBackdrop.AbsoluteUri.Contains("http"))
					{
						File.Copy(primaryBackdrop.LocalPath, Path.Combine(di.FullName, FanArtFileName),true);
					}
				}
				
				if(configurationAddIn.UseExtraFanArt)
				{
					if(Directory.Exists(Path.Combine(di.FullName, ExtraFanArtDirectory)))
					{
						if(configurationAddIn.DeleteImage)
						{
							Directory.Delete(Path.Combine(di.FullName, ExtraFanArtDirectory),true);
						}
					}
					else
					{
						Directory.CreateDirectory(Path.Combine(di.FullName, ExtraFanArtDirectory));
					}
					
					for (int i = 1; i < backdrops.Count; i++) {
						var backdrop = backdrops[i];
						
						if(!backdrop.AbsoluteUri.Contains("http"))
						{
							File.Copy(backdrop.LocalPath, Path.Combine(di.FullName, ExtraFanArtDirectory, "fanart" + i + ".jpg"), true);
						}
					}
				}
			}
		}
		
		private void SaveTrailer(List<Trailer> trailers, string mediaLocation)
		{
			if(trailers.Any())
			{
				DirectoryInfo di = new DirectoryInfo(mediaLocation);
				
				if(File.Exists(mediaLocation))
				{
					di = di.Parent;
				}
				
				var primaryTrailer = trailers.First();
				
				if(!primaryTrailer.DefaultPath.AbsoluteUri.Contains("http"))
				{
					File.Copy(primaryTrailer.DefaultPath.LocalPath, Path.Combine(di.FullName, "movie-trailer" + new FileInfo(primaryTrailer.DefaultPath.LocalPath).Extension), true);
				}
			}
		}
		
		private string SaveActor(string mediaLocation, Uri actorImage, string actorName)
		{
			DirectoryInfo di = new DirectoryInfo(mediaLocation);
			
			if(File.Exists(mediaLocation))
			{
				di = di.Parent;
			}
			
			if(!Directory.Exists(Path.Combine(di.FullName, ".actor")))
			{
				Directory.CreateDirectory(Path.Combine(di.FullName, ".actor"));
			}
			
			if(actorImage != null)
			{
				if(!actorImage.AbsoluteUri.Contains("http"))
				{
					File.Copy(actorImage.LocalPath, Path.Combine(di.FullName, ".actor" , actorName.Replace(' ', '_') + ".tbn"), true);
				}
			}
			
			return string.Empty;
		}
	}
}